const fs = require('fs');
const path = require('path');
const sharp = require('sharp');

// 主包中的图片目录
const MAIN_PACKAGE_IMAGE_DIRS = [
  'miniprogram/images/tabbar',
  'miniprogram/images/icons'
];

// 创建输出目录
const OUTPUT_DIR = 'optimized_images';
if (!fs.existsSync(OUTPUT_DIR)) {
  fs.mkdirSync(OUTPUT_DIR);
}

// 获取文件大小（KB）
function getFileSizeInKB(filePath) {
  if (fs.existsSync(filePath)) {
    const stats = fs.statSync(filePath);
    return stats.size / 1024;
  }
  return 0;
}

// 压缩单个图片
async function compressImage(imagePath, targetSizeKB = 30) {
  try {
    const fileName = path.basename(imagePath);
    const outputPath = path.join(OUTPUT_DIR, fileName);
    const originalSize = getFileSizeInKB(imagePath);
    
    console.log(`处理图片: ${imagePath} (${originalSize.toFixed(2)}KB)`);
    
    // 如果图片已经小于目标大小，只需复制
    if (originalSize <= targetSizeKB) {
      console.log(`  图片已经足够小 (${originalSize.toFixed(2)}KB <= ${targetSizeKB}KB), 直接复制`);
      fs.copyFileSync(imagePath, outputPath);
      return {
        path: imagePath,
        originalSize,
        newSize: originalSize,
        status: 'copied'
      };
    }
    
    // 获取图片格式
    const ext = path.extname(imagePath).toLowerCase();
    
    // 使用sharp处理图片
    let image = sharp(imagePath);
    
    // 获取图片元数据
    const metadata = await image.metadata();
    
    // 初始质量和调整策略
    let quality = 80;
    let width = metadata.width;
    
    // 如果是大图片，先调整尺寸
    if (originalSize > 100) {
      // 调整大小到原来的80%
      width = Math.floor(width * 0.8);
      image = image.resize(width);
    }
    
    // 根据图片类型选择压缩方式
    let buffer;
    if (ext === '.jpg' || ext === '.jpeg') {
      buffer = await image
        .jpeg({ quality })
        .toBuffer();
    } else if (ext === '.png') {
      buffer = await image
        .png({ quality })
        .toBuffer();
    } else {
      // 其他格式转为webp (更小)
      buffer = await image
        .webp({ quality })
        .toBuffer();
    }
    
    // 检查压缩后大小
    let compressedSize = buffer.length / 1024;
    
    // 如果还是太大，继续压缩直到达到目标大小或无法再压缩
    let attempts = 0;
    while (compressedSize > targetSizeKB && attempts < 3) {
      attempts++;
      
      // 进一步调整尺寸和质量
      width = Math.floor(width * 0.9);
      quality = Math.max(quality - 10, 60); // 不要低于60的质量
      
      if (ext === '.jpg' || ext === '.jpeg') {
        buffer = await image
          .resize(width)
          .jpeg({ quality })
          .toBuffer();
      } else if (ext === '.png') {
        buffer = await image
          .resize(width)
          .png({ quality })
          .toBuffer();
      } else {
        buffer = await image
          .resize(width)
          .webp({ quality })
          .toBuffer();
      }
      
      compressedSize = buffer.length / 1024;
      console.log(`  尝试 #${attempts}: 尺寸=${width}, 质量=${quality}, 大小=${compressedSize.toFixed(2)}KB`);
    }
    
    // 保存压缩后的图片
    fs.writeFileSync(outputPath, buffer);
    
    console.log(`压缩完成: ${originalSize.toFixed(2)}KB -> ${compressedSize.toFixed(2)}KB (${(100 - compressedSize/originalSize*100).toFixed(2)}% 减少)`);
    
    return {
      path: imagePath,
      originalSize,
      newSize: compressedSize,
      status: 'compressed'
    };
  } catch (error) {
    console.error(`压缩失败: ${imagePath}`, error);
    return {
      path: imagePath,
      error: error.message,
      status: 'error'
    };
  }
}

// 处理目录中的所有图片
async function processDirectory(directory) {
  console.log(`处理目录: ${directory}`);
  
  // 读取目录中的所有文件
  const files = fs.readdirSync(directory);
  const imageFiles = files.filter(file => {
    const ext = path.extname(file).toLowerCase();
    return ['.jpg', '.jpeg', '.png', '.gif', '.webp'].includes(ext);
  });
  
  console.log(`找到 ${imageFiles.length} 个图片文件`);
  
  // 创建目标子目录
  const subdir = path.basename(directory);
  const outputSubdir = path.join(OUTPUT_DIR, subdir);
  if (!fs.existsSync(outputSubdir)) {
    fs.mkdirSync(outputSubdir, { recursive: true });
  }
  
  // 处理每个图片
  const results = [];
  for (const file of imageFiles) {
    const imagePath = path.join(directory, file);
    // tabBar图标和图标文件较小，设置不同的目标大小
    const targetSize = directory.includes('tabbar') ? 10 : 20;
    const result = await compressImage(imagePath, targetSize);
    
    // 将压缩后的图片移动到正确的子目录
    if (result.status === 'compressed' || result.status === 'copied') {
      const tempPath = path.join(OUTPUT_DIR, file);
      const finalPath = path.join(outputSubdir, file);
      if (fs.existsSync(tempPath)) {
        fs.renameSync(tempPath, finalPath);
      }
    }
    
    results.push(result);
  }
  
  return results;
}

// 主函数
async function main() {
  console.log('开始优化主包图片...');
  
  let totalOriginalSize = 0;
  let totalNewSize = 0;
  let totalFiles = 0;
  let successCount = 0;
  let errorCount = 0;
  
  // 处理每个目录
  for (const dir of MAIN_PACKAGE_IMAGE_DIRS) {
    if (fs.existsSync(dir)) {
      const results = await processDirectory(dir);
      
      // 统计结果
      const dirOriginalSize = results.reduce((sum, r) => sum + (r.originalSize || 0), 0);
      const dirNewSize = results.reduce((sum, r) => sum + (r.newSize || 0), 0);
      const dirSuccessCount = results.filter(r => r.status === 'compressed' || r.status === 'copied').length;
      const dirErrorCount = results.filter(r => r.status === 'error').length;
      
      console.log(`\n目录 ${dir} 处理完成:`);
      console.log(`- 图片数量: ${results.length}`);
      console.log(`- 成功处理: ${dirSuccessCount}`);
      console.log(`- 处理失败: ${dirErrorCount}`);
      console.log(`- 总大小: ${dirOriginalSize.toFixed(2)}KB -> ${dirNewSize.toFixed(2)}KB`);
      console.log(`- 节省: ${(dirOriginalSize - dirNewSize).toFixed(2)}KB (${((1 - dirNewSize/dirOriginalSize) * 100).toFixed(2)}%)`);
      
      totalOriginalSize += dirOriginalSize;
      totalNewSize += dirNewSize;
      totalFiles += results.length;
      successCount += dirSuccessCount;
      errorCount += dirErrorCount;
    } else {
      console.log(`目录不存在: ${dir}`);
    }
  }
  
  console.log('\n总体优化结果:');
  console.log(`- 总图片数: ${totalFiles}`);
  console.log(`- 成功处理: ${successCount}`);
  console.log(`- 处理失败: ${errorCount}`);
  console.log(`- 总大小: ${totalOriginalSize.toFixed(2)}KB -> ${totalNewSize.toFixed(2)}KB`);
  console.log(`- 总节省: ${(totalOriginalSize - totalNewSize).toFixed(2)}KB (${((1 - totalNewSize/totalOriginalSize) * 100).toFixed(2)}%)`);
  
  console.log(`\n优化后的图片保存在 "${OUTPUT_DIR}" 目录中`);
  console.log('请替换主包中的图片以减小包体积');
  console.log('您也可以考虑移动一些非必要图片到云存储中');
}

// 运行主函数
main().catch(console.error); 